/*
 * River.java
 * Team QQ 2011
 */

package com.google.code.timetrail.backend;

import java.util.List;
import java.util.Random;

/**
 * @author Jake Gibel
 * @version 1.0.0
 */
public class River {
	/**
	 * the depth of the river
	 */
	private final int depth;

	/**
	 * the data that the current game has
	 */
	private final Control gameControl;

	/**
	 * The price of taking the ferry
	 */
	private static final int FERRY_PRICE = 40;

	/**
	 * Value VALUE_HUNDRED
	 */
	private static final int VALUE_HUNDRED = 100;

	/**
	 * Position POSITION_TWO
	 */
	private static final int POSITION_TWO = 2;

	/**
	 * Initial chance in ford
	 */
	private static final double INITIAL_CHANCE = 0.3;

	/**
	 * Depth limit
	 */
	private static final double DEPTH_LIMIT = 3.0;

	/**
	 * Initial chance in caulk
	 */
	private static final double CHANCE_CAULK = 0.8;

	/**
	 * chance of random item removal
	 */
	private static final double CHANCE_ITEM = 0.2;

	/**
	 * Value 11
	 */
	private static final int VALUE_ELEVEN = 11;

	/**
	 * Creates a new river at a given place
	 * 
	 * @param gameControl
	 *            the game's current data
	 * @param place
	 *            the location of the river
	 */
	public River(Control gameControl, Place place) {
		this.depth = place.getRiverDepth();
		this.gameControl = gameControl;

	}

	/**
	 * The option to take a ferry. The user loses money but makes it safely
	 * across
	 * 
	 * @return The result of your taking of the ferry
	 */
	public String takeFerry() {
		if (gameControl
				.getInv()
				.canRemoveItem(
						FERRY_PRICE
								- ((FERRY_PRICE * gameControl.getPlayer()
										.getSkills()[POSITION_TWO]) / VALUE_HUNDRED),
						gameControl.getInv().getMoney())) {
			gameControl
					.getInv()
					.removeItem(
							FERRY_PRICE
									- ((FERRY_PRICE * gameControl.getPlayer()
											.getSkills()[POSITION_TWO]) / VALUE_HUNDRED),
							gameControl.getInv().getMoney());
			return "You payed "
					+ (FERRY_PRICE - ((FERRY_PRICE * gameControl.getPlayer()
							.getSkills()[POSITION_TWO]) / VALUE_HUNDRED))
					+ " dollars and travelled safely across";
		} else {
			return "You don't have enough money to make it across!";
		}

	}

	/**
	 * The option to ford the river. The chance to flip increases with the
	 * depth. You automatically flip if river depth is over 3.0 meters
	 * 
	 * @return The result of your choosing to ford the river
	 */
	public String ford() {
		double chanceOfFlip = INITIAL_CHANCE;
		chanceOfFlip += ((double) depth) / DEPTH_LIMIT;
		return flip(chanceOfFlip);
	}

	/**
	 * The option you caulk your ship and cross the river. The chance of
	 * flipping is static
	 * 
	 * @return The result of your choosing to caulk and cross.
	 */
	public String caulk() {
		return flip(CHANCE_CAULK);
	}

	/**
	 * Determines the outcome of your attempt to cross the river. Possible
	 * outcomes are being successful, losing a random amount of a random item,
	 * and having a player killed.
	 * 
	 * @param chanceOfFlip
	 *            the chance of your flipping while crossing
	 * @return The outcome of the crossing
	 */
	public String flip(double chanceOfFlip) {

		final Random rand = new Random();
		if (rand.nextDouble() > chanceOfFlip) {
			return "You sucessfully made it across the time stream";

		} else if (rand.nextDouble() > CHANCE_ITEM) {
			Item randomItem = gameControl.getInv().getRandomItem();
			if (randomItem.getCurrentAmount() == 0) {
				for (int i = 0; i < VALUE_ELEVEN; i++) {
					randomItem = gameControl.getInv().getRandomItem();
					if (randomItem.getCurrentAmount() > 0) {
						break;
					}
				}
				if (randomItem.getCurrentAmount() == 0) {
					return "You sucessfully made it across the time stream";
				}
			}
			final int removedAmount = rand.nextInt(randomItem
					.getCurrentAmount());
			gameControl.getInv().removeItem(removedAmount, randomItem);
			return "You lost " + removedAmount + " of your "
					+ randomItem.toString();
		} else {

			final List<Person> players = gameControl.getMembers();
			final Person killedPlayer = players.get(players.size() - 1);
			if (players.size() > 1
					&& !killedPlayer.isDead()
					&& killedPlayer.getSkills()[0] > rand
							.nextInt(VALUE_HUNDRED)) {
				killedPlayer.die();
				return "Your ship flipped, and " + killedPlayer.toString()
						+ " fell into the time stream and aged to their doom";
			} else {
				return "You sucessfully made it across the river";
			}
		}
	}

	/**
	 * @return the price of the ferry
	 */
	public int getFerryPrice() {
		return FERRY_PRICE
				- ((FERRY_PRICE * gameControl.getPlayer().getSkills()[POSITION_TWO]) / VALUE_HUNDRED);
	}

	/**
	 * @return a String representation of the river
	 */
	public String toString() {
		return "a time stream that is " + depth + " feet deep.";
	}
}
